package com.hksj.am.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hksj.am.mapper.AmmoniaDeviceMapper;
import com.hksj.am.query.AmmoniaDeviceHistoryQuery;
import com.hksj.am.query.AmmoniaDeviceQuery;
import com.hksj.am.vo.AmmoniaDeviceHistoryVO;
import com.hksj.am.vo.AmmoniaDeviceVO;
import com.hksj.am.vo.ExportAmmoniaHistoryVO;
import com.hksj.base.service.DefaultDeviceService;
import com.hksj.cbm.util.CellStyleStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


/**
 * description：氨气设备服务类
 *
 * @author niexiang
 * @date 2024/11/07 11:48
 */
@Service
public class AmmoniaDeviceService {

    private static final Logger log = LoggerFactory.getLogger(AmmoniaDeviceService.class);

    @Autowired
    private AmmoniaDeviceMapper ammoniaDeviceMapper;

    @Autowired
    private DefaultDeviceService defaultDeviceService;


    /**
     * 根据分页查询条件查询氨气设备信息
     * 此方法通过接收一个查询对象来获取分页参数及查询条件，然后调用数据库操作以分页形式获取氨气设备信息
     * 除此之外，它还为每个设备查询其最大浓度值，并设置到设备信息中
     *
     * @param query 分页查询条件对象，包含页码和页面大小等信息
     * @return 返回一个分页对象，其中包含查询到的氨气设备信息列表
     */
    public IPage<AmmoniaDeviceVO> queryAmmoniaDeviceByPaging(AmmoniaDeviceQuery query){
        // 创建分页对象，初始化页码和页面大小
        IPage<AmmoniaDeviceVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        // 调用Mapper方法，根据分页和查询条件获取氨气设备信息列表
        List<AmmoniaDeviceVO> list = ammoniaDeviceMapper.queryAmmoniaDeviceByPaging(page, query);

        // 遍历设备信息列表，为每个设备查询其最大浓度值
        list.forEach(item->{
            // 根据产品ID获取设备数据表名称
            String tableName = defaultDeviceService.getTableName(item.getProductId());
            // 查询该设备的最大浓度值
            Double maxConcentration = ammoniaDeviceMapper.queryMaxConcentration(tableName, item.getDeviceId());
            // 设置设备的最大浓度值，如果没有最大浓度值，则设置为0.0
            item.setMaxConcentration(maxConcentration != null ? maxConcentration : 0.0);
        });

        // 将处理后的设备信息列表设置回分页对象
        page.setRecords(list);
        // 返回填充了设备信息的分页对象
        return page;
    }


    /**
     * 查询氨气设备历史记录列表
     *
     * @param query 包含查询条件的对象，用于指定查询参数
     * @return 返回一个氨气设备历史记录的列表，如果查询失败或无记录，则返回空列表
     */
    public List<AmmoniaDeviceHistoryVO> queryAmmoniaDeviceHistoryList(AmmoniaDeviceHistoryQuery query) {
        // 获取数据表名称
        String tableName = defaultDeviceService.getTableName(query.getProductId());
        List<AmmoniaDeviceHistoryVO> list = new ArrayList<>();
        try {
            // 查询氨气设备历史记录列表
            list = ammoniaDeviceMapper.queryAmmoniaDeviceHistoryList(query, tableName);
        }catch (Exception e){
            // 记录查询错误信息
            log.error("Error querying table {}: {}", tableName, e.getMessage(), e);
        }
        // 返回查询结果列表
        return list;
    }


    /**
     * 根据分页查询条件查询氨气设备历史记录
     *
     * @param query 分页查询参数，包含产品ID、页码、页面大小等信息
     * @return 返回一个分页对象，包含氨气设备历史记录列表和总记录数
     */
    public IPage<AmmoniaDeviceHistoryVO> queryAmmoniaDeviceHistoryByPaging(AmmoniaDeviceHistoryQuery query) {
        // 获取设备历史记录所在表的表名
        String tableName = defaultDeviceService.getTableName(query.getProductId());

        // 初始化分页对象
        IPage<AmmoniaDeviceHistoryVO> page = new Page<>(query.getPageNum(), query.getPageSize());

        // 初始化历史记录列表和总记录数
        List<AmmoniaDeviceHistoryVO> list = new ArrayList<>();
        Long total = 0L;

        try {
            // 查询氨气设备历史记录列表
            list = ammoniaDeviceMapper.queryAmmoniaDeviceHistoryList(query, tableName);

            // 查询氨气设备历史记录总条数
            total = ammoniaDeviceMapper.queryAmmoniaDeviceHistoryCount(query, tableName);
        }catch (Exception e){
            // 记录查询异常信息
            log.error("查询异常的表 {}: {}", tableName, e.getMessage(), e);
        }

        // 设置分页对象的记录列表和总记录数
        page.setRecords(list);
        page.setTotal(total);

        // 返回分页对象
        return page;
    }


    /**
     * 导出氨气设备历史数据
     *
     * @param query 查询条件，用于筛选氨气设备历史记录
     * @param response HTTP响应对象，用于输出导出的文件
     */
    public void exportAmmoniaDeviceHistory(AmmoniaDeviceHistoryQuery query, HttpServletResponse response) {
        // 查询氨气设备历史数据列表
        List<AmmoniaDeviceHistoryVO> list = queryAmmoniaDeviceHistoryList(query);

        // 将查询结果转换为导出所需的格式
        List<ExportAmmoniaHistoryVO> data = IntStream.range(0, list.size())
                .mapToObj(index -> {
                    AmmoniaDeviceHistoryVO deviceHistory = list.get(index);
                    ExportAmmoniaHistoryVO vo = new ExportAmmoniaHistoryVO();
                    vo.setSeq(index + 1);
                    vo.setNumberValue(deviceHistory.getNumberValue());
                    vo.setReportTime(deviceHistory.getCreateTime());
                    return vo;
                })
                .collect(Collectors.toList());

        // 准备表头数据
        List<List<String>> header= new ArrayList<>();
        header.add(Collections.singletonList("序号"));
        header.add(Collections.singletonList("氨气浓度（ppm）"));
        header.add(Collections.singletonList("上报时间"));

        // 生成文件名
        String fileName = "氨气设备历史数据" +
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                        .format(new Date()) +
                ".xlsx";
        try {
            // 设置响应内容类型和文件名
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));

            // 使用EasyExcel库将数据写入Excel文件
            EasyExcel.write(response.getOutputStream(), ExportAmmoniaHistoryVO.class)
                    .registerWriteHandler(new CellStyleStrategy(Collections.singletonList(0),new WriteCellStyle(), new WriteCellStyle()))
                    .head(header)
                    .sheet("sheet1")
                    .doWrite(data);
        }catch (Exception e){
            // 记录导出过程中的异常
            log.error("氨气设备历史导出异常: {}", e.getMessage(), e);
        }
    }

}
